﻿using OA.IDAL;
using OA.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace OA.DAL
{
    public class BaseDAL<T>  where T: BaseModel, new()
    {
      
        public OADbContext db { get; set; }

        public void Add(T entity)
        {
            //db.Set<T>().Add(entity);

            db.Entry(entity).State = EntityState.Added;
            //return db.SaveChanges();
        }

        public void Edit(T entity)
        {
            db.Entry(entity).State = EntityState.Modified;
            //return db.SaveChanges();
        }

        public void Delete(T entity)
        {
            db.Entry(entity).State = EntityState.Deleted;
            //return db.SaveChanges();
        }

        public void Delete(int id)
        {
            var obj = new T() { Id = id };
            db.Entry(obj).State = EntityState.Deleted;
            //return db.SaveChanges();
        }


        public async Task<T> GetEntityAsync(int id,bool tracking=false)
        {
            if (tracking)
                return await db.Set<T>().FindAsync(id);

            return await db.Set<T>().AsNoTracking().FirstOrDefaultAsync(x => x.Id == id);
        }
        public async Task<T> GetEntityAsync(Expression<Func<T,bool>> where, bool tracking = false)
        {
            var query = db.Set<T>();

            if (tracking)
                return await query.FirstOrDefaultAsync(where);

            return await query.AsNoTracking().FirstOrDefaultAsync(where);
        }

        public IQueryable<T> GetList(Expression<Func<T, bool>> where)
        {
            return db.Set<T>().Where(where).AsNoTracking();
        }

        public IQueryable<T> GetList<O>(Expression<Func<T,bool>> where,int pageIndex,int pageSize,out int total,Expression<Func<T,O>> orderFieled,bool isAsc=true)
        {
            var query = db.Set<T>().Where(where);
            total = query.Count();

            if (isAsc)
                query = query.OrderBy(orderFieled);
            else
                query = query.OrderByDescending(orderFieled);

            return query.Skip(pageSize * (pageIndex - 1)).Take(pageSize);

        }

        public int ExecuteSql(string sql, SqlParameter[] sp=null)
        {
            return db.Database.ExecuteSqlCommand(sql, sp);
        }

    }
}
